From 0a15e93927d97364a3331d25c5db70971688b91d Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 15 Jun 2007 12:36:04 -0600 Subject: [PATCH] [IA64] RBS is now in vcpu_guest_context_regs. As there is not anymore local variable of type vcpu_guest_context_regs in the hypervisor the rbs field (16KB) can be put in the structure. Code to read/write the field added. Signed-off-by: Tristan Gingold --- xen/arch/ia64/xen/domain.c | 22 +++++++++++++++++++--- xen/include/public/arch-ia64.h | 22 +++++++++++----------- xen/include/public/foreign/reference.size | 4 ++-- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 09f3759175..f85214e4b6 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -361,6 +361,10 @@ void startup_cpu_idle_loop(void) # error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)." #endif +#if (IA64_RBS_OFFSET % 512) != IA64_GUEST_CONTEXT_RBS_OFFSET +# error "arch-ia64.h: IA64_GUEST_CONTEXT_RBS_OFFSET must be adjusted." +#endif + void hlt_timer_fn(void *data) { struct vcpu *v = data; @@ -610,6 +614,7 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) struct vcpu_tr_regs *tr = &c.nat->regs.tr; struct cpu_user_regs *uregs = vcpu_regs(v); int is_hvm = VMX_DOMAIN(v); + unsigned int rbs_size; c.nat->regs.b[6] = uregs->b6; c.nat->regs.b[7] = uregs->b7; @@ -638,7 +643,8 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) c.nat->regs.pr = uregs->pr; c.nat->regs.b[0] = uregs->b0; - c.nat->regs.ar.bsp = uregs->ar_bspstore + (uregs->loadrs >> 16); + rbs_size = uregs->loadrs >> 16; + c.nat->regs.ar.bsp = uregs->ar_bspstore + rbs_size; c.nat->regs.r[1] = uregs->r1; c.nat->regs.r[12] = uregs->r12; @@ -683,6 +689,9 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) /* FIXME: to be reordered. */ c.nat->regs.nats = uregs->eml_unat; + if (rbs_size < sizeof (c.nat->regs.rbs)) + memcpy (c.nat->regs.rbs, (char *)v + IA64_RBS_OFFSET, rbs_size); + c.nat->privregs_pfn = get_gpfn_from_mfn (virt_to_maddr(v->arch.privregs) >> PAGE_SHIFT); @@ -713,10 +722,12 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) { struct cpu_user_regs *uregs = vcpu_regs(v); struct domain *d = v->domain; + int was_initialised = v->is_initialised; + unsigned int rbs_size; int rc; /* Finish vcpu initialization. */ - if (!v->is_initialised) { + if (!was_initialised) { if (d->arch.is_vti) rc = vmx_final_setup_guest(v); else @@ -761,7 +772,12 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) uregs->pr = c.nat->regs.pr; uregs->b0 = c.nat->regs.b[0]; - uregs->loadrs = (c.nat->regs.ar.bsp - c.nat->regs.ar.bspstore) << 16; + rbs_size = c.nat->regs.ar.bsp - c.nat->regs.ar.bspstore; + /* Protection against crazy user code. */ + if (!was_initialised) + uregs->loadrs = (rbs_size) << 16; + if (rbs_size == (uregs->loadrs >> 16)) + memcpy ((char *)v + IA64_RBS_OFFSET, c.nat->regs.rbs, rbs_size); uregs->r1 = c.nat->regs.r[1]; uregs->r12 = c.nat->regs.r[12]; diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index cf0e5435eb..f8f462b004 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -451,7 +451,8 @@ struct vcpu_guest_context_regs { unsigned long psr; unsigned long cfm; unsigned long pr; - unsigned long nats; /* NaT bits for r1-r31. */ + unsigned int nats; /* NaT bits for r1-r31. */ + unsigned int bnats; /* Nat bits for banked registers. */ union vcpu_ar_regs ar; union vcpu_cr_regs cr; struct pt_fpreg f[128]; @@ -469,18 +470,17 @@ struct vcpu_guest_context_regs { struct vcpu_tr_regs tr; -#if 0 - /* - * The vcpu_guest_context structure is allocated on the stack in - * a few places. With this array for RBS storage, that structure - * is a bit over 21k. It looks like maybe we're blowing the stack - * and causing rather random looking failures on a couple systems. - * Remove since we're not actually using it for now. - */ - + /* + * The rbs is intended to be the image of the stacked registers still + * in the cpu (not yet stored in memory). It is laid out as if it + * were written in memory at an 512 (64*8) * aligned address + offset. + * The offset is IA64_RBS_OFFSET % 512. + * rbs_nat contains NaT bits for the remaining rbs registers. + */ /* Note: loadrs is 2**14 bytes == 2**11 slots. */ +#define IA64_GUEST_CONTEXT_RBS_OFFSET 448 unsigned long rbs[2048]; -#endif + unsigned long rbs_nat; }; struct vcpu_guest_context { diff --git a/xen/include/public/foreign/reference.size b/xen/include/public/foreign/reference.size index a3843013a5..a157136818 100644 --- a/xen/include/public/foreign/reference.size +++ b/xen/include/public/foreign/reference.size @@ -8,8 +8,8 @@ cpu_user_regs | 68 200 496 xen_ia64_boot_param | - - 96 ia64_tr_entry | - - 32 vcpu_tr_regs | - - 512 -vcpu_guest_context_regs | - - 5488 -vcpu_guest_context | 2800 5168 5520 +vcpu_guest_context_regs | - - 21872 +vcpu_guest_context | 2800 5168 21904 arch_vcpu_info | 24 16 0 vcpu_time_info | 32 32 32 vcpu_info | 64 64 48 -- 2.30.2